#ifndef G3_PARTICLE_SYS_H
#define G3_PARTICLE_SYS_H

#include "color.h"
#include "lua_particle_sys.h"

#include "res/res_texture_mgr.h"
#include "math/m_intersection.h"
#include "math/m_plane.h"

#include <list>

namespace G3 {

enum COLL_TYPE {
	GCT_BOUNCE = 0,
	GCT_STICK = 1,
	GCT_RECYCLE = 2,
	GCT_SLIPPERY = 3
};

class COLL_MATERIAL {
	public:
		COLL_MATERIAL ();
		~COLL_MATERIAL ();

		float Elasticity;
		float Friction;
		COLL_TYPE Type;
};

class COLL_POLYGON3F {
	public:
		COLL_POLYGON3F ();
		~COLL_POLYGON3F ();

		std::vector<uint> Vertices;
		G3::PLANE3F Plane;
		uint MaterialID;

		COLL_POLYGON3F& operator= (const COLL_POLYGON3F &cp);

//==============================================================================
// Gets a POLYGON3X from the COLL_POLYGON3X class
//==============================================================================
		G3::POLYGON3F GetPolygon (std::vector<G3::VEC3F> *aVertices);

		void Clear ();
};

class COLL_MESH {
	public:
		COLL_MESH ();
		~COLL_MESH ();

		std::vector<COLL_MATERIAL> Materials;
		std::vector<COLL_POLYGON3F> Polygons;
		std::vector<G3::VEC3F> Vertices;

//==============================================================================
// Recalculates planes in the collision mesh
//==============================================================================
		void CalcPlanes ();

		void Render ();

		void Clear ();
};

class PARTICLE {
	public:
		PARTICLE ();

		G3::VEC3F Position;
		G3::VEC3F Velocity;
		G3::COL4F Color;
		bool Stuck;
		float Mass;
		float Birth;

		PARTICLE& operator= (const PARTICLE &p);

//==============================================================================
// Dumps a single particle into the log
//==============================================================================
		void Dump (LOG *aLog);
};

class PARTICLE_SYSTEM {
	public:
		PARTICLE_SYSTEM ();
		~PARTICLE_SYSTEM ();

		COLL_MESH *CollGeom;

		uint NumMaxParticles;
		uint NumToRelease;
		float ReleaseInterval;
		float LifeCycle;
		float Size;
		float Mass;
		COL4F Color;
		VEC3F Position;
		VEC3F Velocity;
		VEC3F Gravity;
		VEC3F Wind;
		bool AirResistence;
		float VelocityVar;

		LOG *Log;

		H_TEXTURE Texture;

//==============================================================================
// Initializes the particle system
//
//	TODO:: Software mode, Cg Vertex Shader mode
//==============================================================================
		bool Init ();

//==============================================================================
// Loads the particle system from a stream
//==============================================================================
		bool Load (STREAM *aStream);

//==============================================================================
// Loads the particle system from a file
//==============================================================================
		bool Load (const char *aFilename);

		void Emit();

		void Update (float aElapsedTime = 0.0f);
		void Render ();

		void Restart ();

		void Clear ();

//==============================================================================
// Dumps the particle system into the log
//==============================================================================
		void Dump (LOG *aLog);

	private:
		std::list<PARTICLE> ActiveParticles;
		std::list<PARTICLE> FreeParticles;

		float CurTime;
		float LastUpdate;
		float MaxPointSize;
};

}

#endif

